import store from '../../store'
import axios from 'axios'
import { uid } from 'quasar'
// eslint-disable-next-line no-unused-vars

// console.log(uuid())

function getResponse (res) {
  return {
    data: res.data.data || res.data,
    status: res.status
  }
}

function handleError (e) {
  console.error(e)
  if (e.response.status === 401) {
    setTimeout(() => store.commit('quit'), 0)
  }
  return getResponse(e.response)
}

function getHeaders () {
  const headers = {}

  if (store.state && store.state.auth) {
    headers.Authorization = store.state.auth.token
  }

  return headers
}

/**
 *
 * @param {string} api
 * @param {number} id
 * @param {boolean} loading
 * @param {string} instance
 * @returns {Promise<void>}
 */
export async function getRequest ({ api, id, loading = true, instance = 'instance', params = {} }) {
  const headers = getHeaders()

  if (id) {
    api = api.replace('{id}', id)
  }

  if (this.loading !== undefined && loading) {
    this.loading = true
  }

  try {
    const res = await this.$axios.get(api, { headers, params })

    this[instance] = res.data.data || res.data

    return getResponse(res)
  } catch (e) {
    console.log(e)
    return handleError(e)
  } finally {
    if (this.loading !== undefined && loading) {
      this.loading = false
    }
  }
}

/**
 *
 * @param {string} api
 * @param {number} id
 * @returns {Promise<number>}
 */
export async function actionRequest ({ api, id, type }) {
  const headers = getHeaders()

  if (id) {
    api = api.replace('{id}', id)
  }

  if (type) {
    api = api.replace('{type}', type)
  }

  try {
    await axios.get(api, { headers })
    return 200
  } catch (e) {
    handleError(e)
    return e.response.status
  } finally {
  }
}

/**
 *
 * @param {url} api
 * @param {number} id
 * @param {object} params
 * @param {string} querySet
 * @param {string} count
 * @param {string} mode - set|add|none
 * @param {boolean} loading
 * @param {function} callback
 * @returns {Promise<void>}
 */
export async function getQuerySet ({ api, id, type, page = 1, limit = 10, params = {}, querySet = 'querySet', count = 'count', mode = 'set', callback, loading = true }) {
  const headers = getHeaders()

  if (id) {
    api = api.replace('{id}', id)
  }

  if (type) {
    api = api.replace('{type}', type)
  }

  if (page) {
    params.offset = (page - 1) * limit
  }

  if (limit) {
    params.limit = limit
  }

  if (this.loading !== undefined && loading) {
    this.loading = true
  }

  try {
    const res = await this.$axios.get(api,
      { params, headers }
    )
    const data = res.data

    if (mode === 'set' || !this[querySet]) {
      this[querySet] = data.results
      this[count] = data.count
    } else if (mode === 'add') {
      this[querySet] = this[querySet].concat(data.results)
      this[count] = data.count
    }

    if (this.nextPageQuery !== undefined) {
      this.nextPageQuery = data.next
    }

    if (callback) {
      callback(data)
    }

    return getResponse(res)
  } catch (e) {
    return handleError(e)
  } finally {
    if (this.loading !== undefined && loading) {
      this.loading = false
    }
  }
}

/**
 *
 * @param {string} api
 * @param {number} id
 * @param {object} data
 * @returns {Promise<void>}
 */
export async function postRequest ({ api, id, type, data, loading = true }) {
  if (id) {
    api = api.replace('{id}', id)
  }

  if (type) {
    api = api.replace('{type}', type)
  }

  const headers = getHeaders()

  if (this.loading !== undefined && loading) {
    this.loading = true
  }

  try {
    const res = await this.$axios.post(api, data, { headers })

    return getResponse(res)
  } catch (e) {
    console.log(e)
    return handleError(e)
  } finally {
    if (this.loading !== undefined && loading) {
      this.loading = false
    }
  }
}

export async function deleteInstance ({ api, id }) {
  if (id) {
    api = api.replace('{id}', id)
  }

  const headers = getHeaders()

  try {
    const res = await this.$axios.delete(api, { headers })

    return getResponse(res)
  } catch (e) {
    return handleError(e)
  } finally {
  }
}

export function getMaxPage (count, limit) {
  return Math.ceil(count / limit)
}

export const maxPage = {
  computed: {
    maxPage () {
      return getMaxPage(this.count, this.limit)
    }
  }
}

export function getRoute ({ name, path, params, query }) {
  name = this.$route.name || name
  path = this.$route.path || path

  query = Object.assign({}, this.$route.query, query)
  params = Object.assign({}, this.$route.params, params)

  for (const key in query) {
    if (query[key] === undefined) {
      delete query[key]
    }
  }

  return { name, path, params, query }
}

const LIMIT = 10

async function getOssToken (path) {
  const api = '/api/common/oss_token/'
  const headers = getHeaders()
  const params = { id: path }

  try {
    const res = await axios.get(api, { headers, params })
    return getResponse(res)
  } catch (e) {
    return handleError(e)
  } finally {
  }
}

export const uploadOssMixin = {
  methods: {
    /**
     *
     * @param {File} file
     * @param {string} path
     * @param {Array} format
     * @returns {Promise<{data, status}>}
     */
    async uploadOssFile (file, path, size) {
      let format
      const ossHostUrl = 'https://ageeye-user-image.oss-cn-hangzhou.aliyuncs.com/'

      switch (file.type) {
        case 'image/jpeg':
          format = 'jpg'
          break
        case 'image/png':
          format = 'png'
          break
        case 'image/gif':
          format = 'gif'
          break
        default:
          return { status: 500, data: { msg: '文件格式错误' } }
      }

      const uuid = uid()
      const { width, height } = size

      const { data, status } = await getOssToken(path)

      if (status !== 200) {
        return { status: 500 }
      }

      const formData = new FormData()
      const name = `${uuid}_${width}_${height}.${format}`
      const key = data.dir + name
      const url = ossHostUrl + key

      formData.append('name', name)
      formData.append('key', key)
      formData.append('url', url)
      formData.append('policy', data.policy)
      formData.append('OSSAccessKeyId', data.accessid)
      formData.append('success_action_status', 200)
      formData.append('signature', data.signature)
      formData.append('file', file)

      try {
        const res = await axios.post(data.host, formData, { 'Content-Type': 'multipart/form-data' })
        res.data = { url }

        return getResponse(res)
      } catch (e) {
        return handleError(e)
      } finally {
      }
    }
  }
}

export const querySetBaseMixin = {
  computed: {
    max () {
      return Math.ceil(this.count / (this.limit || LIMIT))
    },
    queryParams () {
      if (this.page) {
        return { page: this.page }
      } else {
        return {}
      }
    },
    more () {
      return this.max > this.page
    }
  },
  methods: {
    /**
     *
     * @param {string} mode set|add
     * @returns {Promise<void>}
     */
    async query (mode) {
      const options = {
        api: this.api,
        page: this.page,
        limit: this.limit || LIMIT,
        type: this.type,
        id: this.id
      }

      if (this.queryParams) {
        options.params = this.queryParams
      }

      if (mode) {
        options.mode = mode
      }

      await this.getQuerySet(options)
    },
    async nextPage () {
      if (!this.nextPageQuery || this.loading) {
        return
      }
      const api = process.env.NODE_ENV === 'development' ? this.nextPageQuery.replace(/https?:\/\/.*?(?=\/)/, '') : this.nextPageQuery

      if (this.loading !== undefined) {
        this.loading = true
      }

      const options = {}

      if (store.state && store.state.auth) {
        options.headers = { Authorization: store.state.auth.token }
      }

      try {
        const res = await this.$axios.get(api, options)
        const data = res.data

        this.querySet = this.querySet.concat(data.results)
        this.count = data.count

        if (this.nextPageQuery !== undefined) {
          this.nextPageQuery = data.next
        }

        return getResponse(res)
      } catch (e) {
        console.log(e)
        return handleError(e)
      } finally {
        if (this.loading !== undefined) {
          this.loading = false
        }
      }
    }
  }
}

export const querySetMixin = Object.assign({
  props: {
    page: {
      type: [Number, String],
      required: false,
      default: 1
    },
    createdQuery: {
      type: Boolean,
      required: false,
      default: true
    },
    updateSetMode: {
      type: String,
      required: false,
      default: 'set'
    }
  },
  data () {
    return {
      // api: '',
      // limit: LIMIT,
      nextPageQuery: null,
      loading: false,
      count: 0,
      querySet: null
    }
  },
  watch: {
    queryParams (query) {
      const route = this.getRoute({ query })
      this.$router.push(route)
      this.query()
    }
  },
  created () {
    if (this.createdQuery) {
      this.query()
    }

    this.$root.$on('scrollBottom', () => {
      if (this.infinite) {
        this.nextPage()
      }
    })
  }
}, querySetBaseMixin)

export const querySetInfiniteMixin = Object.assign({
  props: {
    updateSetMode: {
      type: String,
      required: false,
      default: 'set'
    }
  },
  data () {
    return {
      // api: '',
      page: 1,
      nextPageQuery: null,
      loading: false,
      count: 0,
      querySet: null
    }
  },
  watch: {}
}, querySetBaseMixin)
